{
  description = "Description for the project";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
    denv = {
      url = "github:iliayar/env.nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs@{ flake-parts, denv, nixpkgs, ... }:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs { inherit system; };

      # cangjie_compiler_src = ./cangjie_compiler;
      cangjie_compiler_src = pkgs.fetchgit {
        url = "https://gitcode.com/Cangjie/cangjie_compiler.git";
        rev = "v1.0.0";
        sha256 = "sha256-gMlv2wE/Yr54ABtT5fmd5zCma/pRm5kAqjDQwIUkoUI=";
      };

      cangjie_runtime_src = pkgs.fetchgit {
        url = "https://gitcode.com/Cangjie/cangjie_runtime.git";
        rev = "v1.0.0";
        sha256 = "sha256-KDMnTFTcnLoh3dPujr5kFklCrUnPWbQfLxLKOmaA8R0=";
      };

      llvm_project_rev = "766b8c92396db99a2ae2b7784c3606cb3db8fdeb";
      llvm_project_src = pkgs.fetchgit {
        url = "https://gitcode.com/Cangjie/llvm-project.git";
        rev = llvm_project_rev;
        sha256 = "sha256-4p/3fZlMF1ZfHv8d+TVhkN79mmcY9F69B4kR/sXtFNY=";
      };

      llvm_project_utils_dep_src = pkgs.fetchgit {
        url = "https://gitee.com/openharmony/third_party_llvm-project.git";
        rev = "5c68a1cb123161b54b72ce90e7975d95a8eaf2a4";
        sha256 = "sha256-kqF3l2RdTvTxUy71YCjUDsv/zTlmzoGyZB+DkzTps0g=";
      };

      flatbuffers_src = pkgs.fetchgit {
        url = "https://gitee.com/mirrors_trending/flatbuffers.git";
        rev = "v24.3.25";
        sha256 = "sha256-u5AVjbep3iWwGNXLrkPJUnF8SbmIXlHOYoy3NIlUl/E=";
      };

      flatbuffers_libs_src = pkgs.fetchgit {
        url = "https://gitee.com/openharmony/third_party_flatbuffers.git";
        rev = "OpenHarmony-v6.0-Beta1";
        sha256 = "sha256-IqPR2PZqD6on8CUME98J8CbrMtJT6yt/zO9FG5YZh78=";
      };

      libboundcheck_src = pkgs.fetchgit {
        url = "https://gitee.com/openeuler/libboundscheck.git";
        rev = "v1.1.16";
        sha256 = "sha256-cjztZQ1MbsMqWIi7Q2xAjzHX9/pIORy67ZX8dOUDa2g=";
      };

      bounds_checking_function_src = pkgs.fetchgit {
        url = "https://gitee.com/openharmony/third_party_bounds_checking_function";
        rev = "OpenHarmony-v6.0-Beta1";
        sha256 = "sha256-sTmfAipslJyhBd4IhNN3Tr0c1AaBbEx6tVSNKK79zHA=";
      };

      pcre2_src = pkgs.fetchgit {
        url = "https://gitee.com/openharmony/third_party_pcre2.git";
        rev = "OpenHarmony-v6.0-Beta1";
        sha256 = "sha256-3/KekvCNgm7uLR3Y9BbzhrHrxaYIDURmoG5Sh5VQjTs=";
      };

      commonBuildInputs = with pkgs; [
          python3
          cmake
          ninja

          llvmPackages_15.clang

          libffi
          libxcrypt
          openssl

          gtest

          # for patches
          git
      ];

      cjc = pkgs.stdenv.mkDerivation rec {
          pname = "cjc";
          version = "v1.0.0";

          src = cangjie_compiler_src;

          patches = [
            ./cangjie_compiler.patch
            ./cangjie_compiler_utils_dep.patch
          ];

          buildInputs = commonBuildInputs;

          CC = "${pkgs.llvmPackages_15.clang}/bin/clang";
          CXX = "${pkgs.llvmPackages_15.clang}/bin/clang++";

          configurePhase = ''
            cp --no-preserve=mode,ownership -r ${libboundcheck_src} third_party/boundscheck-v1.1.16
            cp --no-preserve=mode,ownership -r ${flatbuffers_src} third_party/flatbuffers
            cp --no-preserve=mode,ownership -r ${llvm_project_src} third_party/llvm-project
            cp --no-preserve=mode,ownership -r ${llvm_project_utils_dep_src} third_party/llvm-project_utils_dep
            sed -ie 's/NIX_LLVM_VERSION/${llvm_project_rev}/' third_party/CMakeLists.txt
            python3 build.py build  -t release --print-cmd
          '';
          buildPhase = ''
            python3 build.py build  -t release
          '';
          installPhase = ''
            mkdir $out
            python3 build.py install --prefix $out
          '';
      };

      mk-cjc-runtime = { withPrefix }: pkgs.stdenv.mkDerivation rec {
          pname = "cjc-runtime";
          version = "v1.0.0";

          src = cangjie_runtime_src;
          sourceRoot = "cangjie_runtime/runtime";
          buildInputs = commonBuildInputs;

          CC = "${pkgs.llvmPackages_15.clang}/bin/clang";
          CXX = "${pkgs.llvmPackages_15.clang}/bin/clang++";

          configurePhase = ''
            mkdir third_party
            cp --no-preserve=mode,ownership -r ${bounds_checking_function_src} third_party/third_party_bounds_checking_function
          '';
          buildPhase = ''
            VERSION=$(${cjc}/bin/cjc --version | head -n 1 | cut -d' ' -f3)
            python3 build.py build -v $VERSION -t release
          '';
          installPhase = ''
            python3 build.py install ${if withPrefix then "--prefix $out" else ""}
            ${if withPrefix then "" else "cp -r output $out"}
          '';
      };

      cjc-runtime = mk-cjc-runtime { withPrefix = true; };
      cjc-runtime-for-libs = mk-cjc-runtime { withPrefix = false; };

      cjc-with-runtime = pkgs.symlinkJoin {
        name = "cjc-with-runtime";
        paths = [ cjc-runtime cjc ];
      };

      cjc-libs = pkgs.stdenv.mkDerivation rec {
          pname = "cjc-libs";
          version = "v1.0.0";

          src = cangjie_runtime_src;
          sourceRoot = "cangjie_runtime/std";
          buildInputs = commonBuildInputs;

          CC = "${pkgs.llvmPackages_15.clang}/bin/clang";
          CXX = "${pkgs.llvmPackages_15.clang}/bin/clang++";

          configurePhase = ''
            cp --no-preserve=mode,ownership -r ${flatbuffers_libs_src} third_party/flatbuffers
            cp --no-preserve=mode,ownership -r ${pcre2_src} third_party/pcre2-10.44-h1
            cp --no-preserve=mode,ownership -r ${bounds_checking_function_src} third_party/boundscheck-v1.1.16
          '';
          buildPhase = ''
            . ${cjc-with-runtime}/envsetup.sh
            python3 build.py build -t release -L ${cjc-runtime-for-libs}
          '';
          installPhase = ''
            python3 build.py install --prefix $out
          '';
      };

      cangjie-merged = pkgs.buildEnv {
        name = "cangjie-merged";
        paths = [ cjc-with-runtime cjc-libs ];
      };

      cangjie = pkgs.stdenv.mkDerivation rec {
        pname = "cangjie";
        version = "v1.0.0";

        src = cangjie-merged;

        buildInputs = with pkgs; [ makeWrapper ];

        installPhase = ''
            mkdir $out
            cp -L -r ./* $out/
        '';

        postFixup = ''
            wrapProgram $out/bin/cjc \
                --append-flags "-B${pkgs.glibc}/lib -B${pkgs.stdenv.cc.cc}/lib"
        '';
      };

      cangjie-bin = import bin/lts.nix { inherit pkgs; };
    in {
      packages.${system} = {
        inherit cangjie cangjie-bin;
        default = cangjie;
      };
      templates = rec {
        default = compiler;
        compiler = {
          path = ./templates/default;
          description = "Compiler devolpment env";
        };
      };
    };
}
